package com.woniu.mall.service.impl;

import com.woniu.common.entity.ResultCode;
import com.woniu.common.exception.MallException;
import com.woniu.common.utils.IdWorker;
import com.woniu.mall.DTO.SeckillDTO;
import com.woniu.mall.config.MallOrderQueueConfig;
import com.woniu.mall.constant.MallPayInfoConstants;
import com.woniu.mall.constant.SeckillRedisKey;
import com.woniu.mall.entity.CheckOrderInfo;
import com.woniu.mall.pojo.MallOrder;
import com.woniu.mall.pojo.MallSeckill;
import com.woniu.mall.service.IMallSeckillService;
import com.woniu.pay.entity.PayInfo;
import com.woniu.pay.feign.PayFeignClient;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class MultiCreateOrder {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IMallSeckillService seckillService;
    @Autowired
    private PayFeignClient payFeignClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Async
    @SneakyThrows
    public String createSeckillOrder(){
        log.debug("开始多线程下单操作=====");
        //1. 获取一个秒杀下单对象
        SeckillDTO seckillDTO = (SeckillDTO) redisTemplate.boundListOps(SeckillRedisKey.SECKILL_ORDER_QUEUE).rightPop();
        //4. 获取商品信息
        MallSeckill seckill = (MallSeckill) redisTemplate.boundHashOps(SeckillRedisKey.SECKILL_LIST).get(seckillDTO.getProductId() + "");
        //2.调用下单方法
        MallOrder order = seckill(seckillDTO.getProductId(), seckillDTO.getUserId(), seckillDTO.getMobile());
        //3. 修改用户的排队状态，修改为待支付
        seckillDTO.setStatus(2);
        redisTemplate.boundHashOps(SeckillRedisKey.SECKILL_ORDER_STATUS).put(seckillDTO.getMobile(), seckillDTO);


        //5. 准备支付
        PayInfo payInfo = new PayInfo();

        String outTradeNo = order.getOrderId().toString();
        payInfo.setOutTradeNo(outTradeNo);
        payInfo.setSubject(seckill.getProductName());
        payInfo.setTotalAmount(seckill.getPrice());
        payInfo.setReturnUrl(MallPayInfoConstants.RETURN_URL);
        payInfo.setNotifyUrl(MallPayInfoConstants.NOTIFY_URL);
        //6. 将订单编号发送到队列
        //创建订单检查对象
        CheckOrderInfo checkOrderInfo = new CheckOrderInfo();
        checkOrderInfo.setOrderNo(outTradeNo);
        checkOrderInfo.setProductId(seckill.getProductId());
        checkOrderInfo.setProductName(seckill.getProductName());
        rabbitTemplate.convertAndSend(MallOrderQueueConfig.ORDER_EXCHANGE, MallOrderQueueConfig.X_DEAD_LETTER_ROUTING_KEY, checkOrderInfo);

        //7. 发起支付
        String form = (String) payFeignClient.pay(payInfo).getData();

        log.debug("多线程下单操作结束=====");
        return form;
    }



    //秒杀方法
    public MallOrder seckill(Integer productId, Integer userId, String mobile) {
        //从redis中获取秒杀的商品
        MallSeckill seckill = (MallSeckill) redisTemplate.boundHashOps(SeckillRedisKey.SECKILL_LIST).get(productId + "");
        if (seckill == null){
            throw new MallException("秒杀的商品不存在", ResultCode.PRODUCT_NOT_EXIST);
        }
        // 判断库存
        if (seckill.getPsCount() <= 0   ){
            throw new MallException("秒杀商品库存不足", ResultCode.PRODUCT_NO_STOCK);
        }
        //创建订单
        MallOrder order = new MallOrder();
        IdWorker idWorker = new IdWorker(1,0);
        order.setOrderId((int)idWorker.nextId());
        order.setUserId(userId);
        order.setTotalPrice(seckill.getPrice());

        //保存订单到redis中
        redisTemplate.boundHashOps(SeckillRedisKey.SECKILL_ORDER).put(mobile, order);

        //用户处减少优惠券库存

        // 预扣库存
        seckill.setPsCount(seckill.getPsCount() - 1);
        redisTemplate.boundHashOps(SeckillRedisKey.SECKILL_LIST).put(productId + "", seckill);

        return order;
    }

}
